#include<SuperOF.h>
using namespace std;

const string version="1.0.01.079";
string OFK_file;
int main()
{
	color("cyan-l","black",0,0);
	cout<<"OF-keyboard V"<<version<<endl;
	cout<<"if-OF(c)2020-2021"<<endl;
	color("white","black",0,0);
	line();
	cout<<"Please enter the file path:"<<endl; 
	getline(cin,OFK_file);
	if(strstr(OFK_file.c_str(),":")==NULL)
	{
		OFK_file=work_dir()+"\\"+OFK_file;
		fstream _file;
		_file.open(OFK_file.c_str(),ios::in);
		if(!_file)
		{
			error("Can't find the file.");
			warning("Program will close in 5 seconds.");
			Sleep(5000);
			return 0;
		}
	}
	else
	{
		fstream _file;
		_file.open(OFK_file.c_str(),ios::in);
		if(!_file)
		{
			error("Can't find the file.");
			warning("Program will close in 5 seconds.");
			Sleep(5000);
			return 0;
		}
	}
	FILE*file=fopen(OFK_file.c_str(),"r");
	int size=filelength(fileno(file));
	int count;
	for(count=0;fgetc(file)!=EOF;count++);
	fclose(file);
	info("Loading program...");
	line();
	info("Code length:"+int_to_string(count)+".");
	info("Code size:"+int_to_string(size)+"B.");
	freopen(OFK_file.c_str(),"r",stdin);
	info("Program is running now...");
	line();
	int for_time=0; 
	while(1)
	{ 
		for_time++;
		bool flag=true;
		int oper_len;
		char operation_c[128]={""};
		string operation="",line_code=""; 
		getline(cin,line_code);
		if(line_code=="END")
			break;
		for(oper_len=0;oper_len<line_code.length();oper_len++)
		{
			if(line_code[oper_len]==' ')
			{
				flag=false;
				break;
			}
		}
		if(flag)
		{
			error("Cannot find operation code in line "+int_to_string(for_time)+".");
			warning("Program will close in 5 seconds.");
			Sleep(5000);
			return 0;
		}
		if(oper_len>=127)
		{
			error("Operation code is too long in line "+int_to_string(for_time)+".Expect less than 127,read"+int_to_string(oper_len)+".");
			warning("Program will close in 5 seconds.");
			Sleep(5000);
			return 0;
		}
		strncpy(operation_c,line_code.c_str(),oper_len);
		operation=operation_c;
		info("operation:"+operation+".");
		if(operation=="BAGIN")
		{
			info("Program start.");
			continue;
		}
		if(operation=="KD")
		{
			info("Read key down in line "+int_to_string(for_time)+".");
			string x=line_code;
			x.erase(0,oper_len+1);
			if(x.size()!=3 || x[0]!='\'' || x[2]!='\'')
			{
				error("KD in line "+int_to_string(for_time)+" needs to add a ASCII character like 'A'.");
				warning("Program will close in 5 seconds.");
				Sleep(5000);
				return 0;
			}
			info("Key \'"+char_to_string(x[1])+"\' was down.");
			keybd_event(x[1],0,0,0);
			continue;
		}
		if(operation=="W")
		{
			info("Read wait in line "+int_to_string(for_time)+".");
			string x=line_code;
			int num=0;
			x.erase(0,oper_len+1);
			for(int i=0;i<x.length();i++)
			{
				num*=10;
				if(x[i]>='0' && x[i]<='9')
					num+=x[i]-'0';
				else
				{
					error("W in line "+int_to_string(for_time)+" needs to add a number like 3000.");
					warning("Program will close in 5 seconds.");
					Sleep(5000);
					return 0;
				}
			}
			info("Start waiting for "+int_to_string(num)+"ms.");
			Sleep(num);
			info("Finish waiting.");
			continue;
		}
	}
}
